package graph.tests;

/**
 * <p>Title: graphs coding problem</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: </p>
 * @author Jean-Michel Garnier
 * @version 1.0
 */

import java.util.*;

public class DistanceQueue {

    private TreeSet queue;

    public DistanceQueue() {
        queue = new TreeSet();
    }

    public void clear() {
        queue.clear();
    }

    public boolean isEmpty() {
        if (queue.isEmpty()) {
            return true;
        }
        else {
            return false;
        }
    }

    public int getSize() {
        return queue.size();
    }

    public void insert(Object element, int distance) {
        if (element == null) {
            throw new IllegalArgumentException("element must be not null");
        }
        if (distance < 0) {
            throw new IllegalArgumentException("Illegal distance: " + distance);
        }
        QueueElement queueElement = new QueueElement(element, distance);
        queue.add(queueElement);
    }

    // Important a distance queue ordered
    public Object dequeueLowestPriorityElement() {
        if (!isEmpty()) {
            QueueElement queueElement = (QueueElement) queue.first();
            Object element = queueElement.getElement();
            queue.remove(queueElement);
            return element;
        }
        else {
            return null;
        }
    }

    public class QueueElement implements Comparable {
        private Object element;
        private int distance;

        public QueueElement(Object element, int distance) {
            this.element = element;
            this.distance = distance;
        }

        public int getDistance() {
            return distance;
        }
        public Object getElement() {
            return element;
        }
        public int compareTo(Object o) {
            int distanceCompared = ((QueueElement) o).getDistance();
            if (this.distance == distanceCompared) {
                if ( this.element.equals(((QueueElement) o).getElement()) ) {
                    return 0;
                }
                else {
                    // @TODO, why the TreeMap bug if it returns 1 ! I have lost 2 hours searching that point
                    return -1;
                }
            }
            else {
                if (this.distance < distanceCompared) {
                    return -1;
                }
                else {
                    return 1;
                }

            }
        }

        public boolean equals(Object o) {
            if ( this.element.equals(((QueueElement)o).getElement()) && ((QueueElement)o).getDistance() == this.distance) {
                return true;
            }
            else {
                return false;
            }
        }
    } // End Class QueueElement
} // End Class PriorityQueue
